package table

import (
	"database/sql"
	"fmt"
	"db2s/Er"
	"db2s/global"
)

type SumS struct {
	LogSeq           int64
	DBObject         string
	Schema           string
	Table            string
	RowsLimit        int
	BackendTableName string
	ShardName        string
	Partition        string
	SqlFilter        global.SqlFilter
	DB               map[string]*sql.DB
	Input            global.StartPartConfigInputP
}

func Rows(s SumS) (sum int64, err error) {
	var (
		event     = "[Rows]"
		tableRows global.RowsReturnResult
		t         Er.TableSumEr
		g         = global.TableSumInput{
			Db: s.DB,
			TableInfo: global.TableInfo{
				Schema:           s.Schema,
				Table:            s.Table,
				BackendTableName: s.BackendTableName,
				ShardName:        s.ShardName,
				RowsLimit:        s.RowsLimit,
			},
			Input: s.Input,
		}
	)
	if t, err = Er.Sum(Er.TableSum{DBType: s.DBObject}); err != nil {
		errorWriteActive(fmt.Sprintf("(%v) %v get table %v.%v rows sum fail. error is {%v}", s.LogSeq, event, s.Schema, s.Table, err))
		return
	}
	if tableRows, err = t.Rows(g); err == nil && tableRows.Result >= 10000000 {
		sum = int64(tableRows.Result)
		return
	}
	if err != nil {
		vlog = fmt.Sprintf("(%v) %v Failed to obtain the number of statistical rows of table %v.%v, and will be converted to count query!!! error is %v", s.LogSeq, event, s.Schema, s.Table, err)
		errorWriteActive(vlog)
	} else if tableRows.Result < 10000000 {
		vlog = fmt.Sprintf("(%v) %v If the number of statistical rows obtained from table %v.%v is less than 1000w, it will be converted into a count query.", s.LogSeq, event, s.Schema, s.Table)
		warnWriteActive(vlog)
		sum = int64(tableRows.Result)
	}
	return
}
func Count(s SumS) (sum int64, err error) {
	var (
		event     = "[Rows]"
		rowsCount global.CountReturnResult
		t         Er.TableSumEr
		g         = global.TableSumInput{
			LogSeq: s.LogSeq,
			Db:     s.DB,
			TableInfo: global.TableInfo{
				Schema:           s.Schema,
				Table:            s.Table,
				BackendTableName: s.BackendTableName,
				ShardName:        s.ShardName,
				PartitionName:    s.Partition,
				RowsLimit:        s.RowsLimit,
			},
			Input:     s.Input,
			SqlFilter: s.SqlFilter,
		}
	)
	if t, err = Er.Sum(Er.TableSum{DBType: s.DBObject}); err != nil {
		errorWriteActive(fmt.Sprintf("(%v) %v get table %v.%v rows sum fail. error is {%v}", s.LogSeq, event, s.Schema, s.Table, err))
		return
	}
	if rowsCount, err = t.Count(g); err != nil {
		return
	}
	sum = int64(rowsCount.Result)
	return
}
func Sum(dbObject string, Object global.Object, DB map[string]*sql.DB) (sum int64, err error) {
	var (
		rowsCount global.CountReturnResult
		event     = "[tableSum]"
		tableRows global.RowsReturnResult
		t         Er.TableSumEr
		g         = global.TableSumInput{
			LogSeq: Object.ObjectLogSeq,
			Db:     DB,
			TableInfo: global.TableInfo{
				Schema:           Object.Schema,
				Table:            Object.Table,
				BackendTableName: Object.Table,
				ShardName:        "single",
			},
			//SqlFilter: s.SqlFilter,
			Input: Object.Input,
		}
	)
	if t, err = Er.Sum(Er.TableSum{DBType: dbObject}); err != nil {
		vlog = fmt.Sprintf("(%v) %v get table %v.%v rows sum fail. error is {%v}", Object.ObjectLogSeq, event, Object.Schema, Object.Table, err)
		return
	}
	vlog = fmt.Sprintf("(%v) %v start get table %v.%v rows sum...", Object.ObjectLogSeq, event, Object.Schema, Object.Table)
	debugWriteActive(vlog)
	//先查询统计信息
	if tableRows, err = t.Rows(g); err == nil && tableRows.Result >= 10000000 {
		sum = int64(tableRows.Result)
		return
	}
	if err != nil {
		vlog = fmt.Sprintf("(%v) %v Failed to obtain the number of statistical rows of table %v.%v, and will be converted to count query!!! error is %v", Object.ObjectLogSeq, event, Object.Schema, Object.Table, err)
		errorWriteActive(vlog)
	} else if tableRows.Result < 10000000 {
		vlog = fmt.Sprintf("(%v) %v If the number of statistical rows obtained from table %v.%v is less than 1000w, it will be converted into a count query.", Object.ObjectLogSeq, event, Object.Schema, Object.Table)
		warnWriteActive(vlog)
	}
	if rowsCount, err = t.Count(g); err != nil {
		vlog = fmt.Sprintf("%v get table %v.%v rows sum fail!!! error is %v", event, Object.Schema, Object.Table, err)
		warnWriteActive(vlog)
		return
	}
	sum = int64(rowsCount.Result)
	vlog = fmt.Sprintf("(%v) %v get table %v.%v rows sum finish.", Object.ObjectLogSeq, event, Object.Schema, Object.Table)
	infoWriteActive(vlog)
	return
}
